// File Locations.cpp
//
// Purpose: Contains the states for the locations in the game
//
// Author : Bryson King (edited)
// Original Code Provided by: Mat Buckland 2002 (fup@ai-junkie.com)
// Date : 19 March 2013
// --------------------------------------------------------------
#define DEBUG_SECTION

#include "Locations.h"

#include <iostream>
#include <string>
#include <algorithm>

#include "Telegram.h"
#include "MessageDispatcher.h"
#include "MessageTypes.h"
#include "CrudeTimer.h"
#include "EntityNames.h"
#include "Item.h"
#include "InterfaceStructures.h"

using std::cout;
using std::endl;


//------------------------------------------------------------------------methods for BoatOutsideShip
BoatOutsideShip::BoatOutsideShip() : m_oItems()
{
	m_sUserOptions.location_name = "a boat outside the USS Enterprise";

	m_sUserOptions.locations_available[0] = "UP";
	m_sUserOptions.locations_available[1] = "";
	m_sUserOptions.locations_available[2] = "";
	m_sUserOptions.locations_available[3] = "";
	m_sUserOptions.locations_available[4] = "";
	m_sUserOptions.locations_available[5] = "";

	m_sUserOptions.other_options_available[0] = "";
	m_sUserOptions.other_options_available[1] = "";
	m_sUserOptions.other_options_available[2] = "";
	m_sUserOptions.other_options_available[3] = "";
	m_sUserOptions.other_options_available[4] = "";
	m_sUserOptions.other_options_available[5] = "";
	m_sUserOptions.other_options_available[6] = "";
	m_sUserOptions.other_options_available[7] = "";
	m_sUserOptions.other_options_available[8] = "";
	m_sUserOptions.other_options_available[9] = "";
}

CLocation** BoatOutsideShip::RequestDirectionsPossible(int& NumberOfDirections)
{
	NumberOfDirections = 1;
	CLocation** aReturnOptions = new CLocation*[NumberOfDirections];
	aReturnOptions[0] = Elevator1::Instance();
	return aReturnOptions;
}

BoatOutsideShip* BoatOutsideShip::Instance()
{
	static BoatOutsideShip instance;
	return &instance;
}

void BoatOutsideShip::Enter(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Entering the boat outside the ship";
	#endif

	// Add entity to the location
	AddEntityToLocation(pEntity);
}

void BoatOutsideShip::Execute(IPerson* pEntity)
{
//	if (true)
//		pEntity->GetLocationMachine()->ChangeLocation(EDivBerthing::Instance());
}

void BoatOutsideShip::Exit(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Exiting the boat outside the ship";
	#endif

	// Remove entity from location
	RemoveEntityFromLocation(pEntity);
}

bool BoatOutsideShip::OnMessage(IPerson* agent, const Telegram& msg)
{
	//send msg to global message handler
	return false;
}

CItems* BoatOutsideShip::RetrieveItemsAtLocation()
{
	SItem* sTempItem = nullptr;
	CItems* pVisibleList = new CItems();
	// Iterate through items list to add to visible list
	for (int i = 0; i < m_oItems.NumberOfItems(); i++)
	{
		sTempItem = m_oItems.RetrieveItem(i);
		// Check if item is visible, and add to return list if it is
		if (sTempItem->ItemVisibleToPlayer)
			pVisibleList->AddItem(sTempItem);
	}
	return pVisibleList;
}

SItem* BoatOutsideShip::RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy)
{
	userCommand = CUserInterface::UserSelectionPrompt(m_sUserOptions, BoatOutsideShip::Instance(), pEnemy);
	
	if (userCommand == "UP")
	{
		pEntity->GetLocationMachine()->ChangeLocation(Elevator1::Instance());
		return nullptr;
	}
	else
	{
		return nullptr;
	}
}

//------------------------------------------------------------------------methods for EDivBerthing
EDivBerthing::EDivBerthing() : m_oItems()
{
	m_sUserOptions.location_name = "Electrical Division Berthing on the 3rd Deck of\nthe USS Enterprise";

	m_sUserOptions.locations_available[0] = "PORT";
	m_sUserOptions.locations_available[1] = "STBD";
	m_sUserOptions.locations_available[2] = "";
	m_sUserOptions.locations_available[3] = "";
	m_sUserOptions.locations_available[4] = "";
	m_sUserOptions.locations_available[5] = "";

	m_sUserOptions.other_options_available[0] = "LOOK AROUND";
	m_sUserOptions.other_options_available[1] = "";
	m_sUserOptions.other_options_available[2] = "";
	m_sUserOptions.other_options_available[3] = "";
	m_sUserOptions.other_options_available[4] = "";
	m_sUserOptions.other_options_available[5] = "";
	m_sUserOptions.other_options_available[6] = "";
	m_sUserOptions.other_options_available[7] = "";
	m_sUserOptions.other_options_available[8] = "";
	m_sUserOptions.other_options_available[9] = "";

	SItem* pNewItem = new SItem();
	pNewItem->Name = "MAP";
	pNewItem->ItemVisibleToPlayer = false;
	m_oItems.AddItem(pNewItem);
	pNewItem = new SItem();
	pNewItem->Name = "CLIPBOARD";
	pNewItem->ItemVisibleToPlayer = false;
	pNewItem->DamageDonePerAttack = 5;
	m_oItems.AddItem(pNewItem);
}

CLocation** EDivBerthing::RequestDirectionsPossible(int& NumberOfDirections)
{
	NumberOfDirections = 1;
	CLocation** aReturnOptions = new CLocation*[NumberOfDirections];
	aReturnOptions[0] = SecondDeckPart1::Instance();
	return aReturnOptions;
}

EDivBerthing* EDivBerthing::Instance()
{
	static EDivBerthing instance;
	return &instance;
}

void EDivBerthing::Enter(IPerson* pEntity)
{  
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Entering the E-Division Berthing";
	#endif

	// Add entity to the location
	AddEntityToLocation(pEntity);
}

void EDivBerthing::Execute(IPerson* pEntity)
{
	// There is no location logic needed here.
}

void EDivBerthing::Exit(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Exiting the E-Division Berthing";
	#endif

	// Remove entity from location
	RemoveEntityFromLocation(pEntity);
}

bool EDivBerthing::OnMessage(IPerson* agent, const Telegram& msg)
{
	//send msg to global message handler
	return false;
}

CItems* EDivBerthing::RetrieveItemsAtLocation()
{
	SItem* sTempItem = nullptr;
	CItems* pVisibleList = new CItems();
	// Iterate through items list to add to visible list
	for (int i = 0; i < m_oItems.NumberOfItems(); i++)
	{
		sTempItem = m_oItems.RetrieveItem(i);
		// Check if item is visible, and add to return list if it is
		if (sTempItem->ItemVisibleToPlayer)
			pVisibleList->AddItem(sTempItem);
	}
	return pVisibleList;
}

SItem* EDivBerthing::RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy)
{
	SItem* tempItem = nullptr;
	static bool bLookedAround = false;

	userCommand = CUserInterface::UserSelectionPrompt(m_sUserOptions, EDivBerthing::Instance(), pEnemy);

	SetTextColor(FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY);

	if (userCommand == "STBD")
	{
		cout << endl << "The starboard access to exit berthing is blocked by old mattresses and other\nmiscellaneous material. " <<
			"Please make another choice." << endl;
		return nullptr;
	}
	else if (userCommand == "PORT")
	{
		pEntity->GetLocationMachine()->ChangeLocation(SecondDeckPart1::Instance());
		return nullptr;
	}
	else if (userCommand == "LOOK AROUND")
	{
		bLookedAround = true;

		// If there is more than one item available
		if (m_oItems.NumberOfItems() > 1)
		{
			cout << endl << "After taking a look around, you notice some items of interest. ";
			// Loop through the items available
			for (int i=0; i<m_oItems.NumberOfItems(); i++)
			{
				tempItem = m_oItems.RetrieveItem(i);
				// Make item visible to the player
				tempItem->ItemVisibleToPlayer = true;

				if (tempItem->Name == "MAP")
				{
					cout << "A map of the 2nd deck of the USS Enterprise.";
				} else if (tempItem->Name == "CLIPBOARD") {
					cout << "A clipboard that has had the edges sharpened that might make a good weapon in a pinch.";
				}
			}
		// If there is only one item available
		} else if (m_oItems.NumberOfItems() > 0) {
			cout << endl << "After taking a look around, you notice one item of interest. ";
			tempItem = m_oItems.RetrieveItem(0);
			// Make item visible to the player
			tempItem->ItemVisibleToPlayer = true;
			if (tempItem->Name == "MAP")
			{
				cout << "A map of the 2nd deck of the USS Enterprise.";
			} else if (tempItem->Name == "CLIPBOARD") {
				cout << "A clipboard that has had the edges sharpened that might make a good weapon in a pinch.";
			}
		// If there are no items available
		} else {
			cout << endl << "After taking a look around, you do not see anything of interest." << endl;
		}
		return nullptr;
	}
	else if (userCommand == "MAP" || userCommand == "CLIPBOARD")
	{
		// return item taken by user input to player to add to inventory
		return m_oItems.RemoveItem(m_oItems.RetrieveItem(userCommand));
	}
	else
	{
		return nullptr;
	}
}

//------------------------------------------------------------------------methods for SecondDeckPart1
SecondDeckPart1::SecondDeckPart1() : m_oItems()
{
	m_sUserOptions.location_name = "2nd Deck of the USS Enterprise";

	m_sUserOptions.locations_available[0] = "";
	m_sUserOptions.locations_available[1] = "STBD";
	m_sUserOptions.locations_available[2] = "FORE";
	m_sUserOptions.locations_available[3] = "AFT";
	m_sUserOptions.locations_available[4] = "";
	m_sUserOptions.locations_available[5] = "";

	m_sUserOptions.other_options_available[0] = "";
	m_sUserOptions.other_options_available[1] = "";
	m_sUserOptions.other_options_available[2] = "";
	m_sUserOptions.other_options_available[3] = "";
	m_sUserOptions.other_options_available[4] = "";
	m_sUserOptions.other_options_available[5] = "";
	m_sUserOptions.other_options_available[6] = "";
	m_sUserOptions.other_options_available[7] = "";
	m_sUserOptions.other_options_available[8] = "";
	m_sUserOptions.other_options_available[9] = "";
}

CLocation** SecondDeckPart1::RequestDirectionsPossible(int& NumberOfDirections)
{
	NumberOfDirections = 2;
	CLocation** aReturnOptions = new CLocation*[NumberOfDirections];
	aReturnOptions[0] = EDivBerthing::Instance();
	aReturnOptions[1] = AftMessDeck::Instance();
	return aReturnOptions;
}

SecondDeckPart1* SecondDeckPart1::Instance()
{
	static SecondDeckPart1 instance;
	return &instance;
}

void SecondDeckPart1::Enter(IPerson* pEntity)
{  
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Entering the 2nd Deck of the USS Enterprise";
	#endif

	// Add entity to the location
	AddEntityToLocation(pEntity);
}

void SecondDeckPart1::Execute(IPerson* pEntity)
{
//	if (true)
//		pEntity->GetLocationMachine()->ChangeLocation(BoatOutsideShip::Instance());
}

void SecondDeckPart1::Exit(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Exiting the 2nd Deck of the USS Enterprise";
	#endif

	// Remove entity from location
	RemoveEntityFromLocation(pEntity);
}

bool SecondDeckPart1::OnMessage(IPerson* agent, const Telegram& msg)
{
	//send msg to global message handler
	return false;
}

CItems* SecondDeckPart1::RetrieveItemsAtLocation()
{
	SItem* sTempItem = nullptr;
	CItems* pVisibleList = new CItems();
	// Iterate through items list to add to visible list
	for (int i = 0; i < m_oItems.NumberOfItems(); i++)
	{
		sTempItem = m_oItems.RetrieveItem(i);
		// Check if item is visible, and add to return list if it is
		if (sTempItem->ItemVisibleToPlayer)
			pVisibleList->AddItem(sTempItem);
	}
	return pVisibleList;
}

SItem* SecondDeckPart1::RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy)
{
	userCommand = CUserInterface::UserSelectionPrompt(m_sUserOptions, SecondDeckPart1::Instance(), pEnemy);
	
	if (userCommand == "STBD")
	{
		pEntity->GetLocationMachine()->ChangeLocation(EDivBerthing::Instance());

		return nullptr;
	}
	else if (userCommand == "FORE")
	{
		pEntity->GetLocationMachine()->ChangeLocation(AftMessDeck::Instance());

		return nullptr;
	}
	else if (userCommand == "AFT")
	{
//		pEntity->GetLocationMachine()->ChangeLocation(FourDieselSpaceUpper::Instance());

		return nullptr;
	}
	else
	{
		return nullptr;
	}
}

//------------------------------------------------------------------------methods for AftMessDeck
AftMessDeck::AftMessDeck() : m_oItems()
{
	m_sUserOptions.location_name = "the Aft Mess Deck of the USS Enterprise";

	m_sUserOptions.locations_available[0] = "";
	m_sUserOptions.locations_available[1] = "";
	m_sUserOptions.locations_available[2] = "FORE";
	m_sUserOptions.locations_available[3] = "AFT";
	m_sUserOptions.locations_available[4] = "";
	m_sUserOptions.locations_available[5] = "";

	m_sUserOptions.other_options_available[0] = "";
	m_sUserOptions.other_options_available[1] = "";
	m_sUserOptions.other_options_available[2] = "";
	m_sUserOptions.other_options_available[3] = "";
	m_sUserOptions.other_options_available[4] = "";
	m_sUserOptions.other_options_available[5] = "";
	m_sUserOptions.other_options_available[6] = "";
	m_sUserOptions.other_options_available[7] = "";
	m_sUserOptions.other_options_available[8] = "";
	m_sUserOptions.other_options_available[9] = "";
}

CLocation** AftMessDeck::RequestDirectionsPossible(int& NumberOfDirections)
{
	NumberOfDirections = 2;
	CLocation** aReturnOptions = new CLocation*[NumberOfDirections];
	aReturnOptions[0] = AftBombXferArea::Instance();
	aReturnOptions[1] = SecondDeckPart1::Instance();
	return aReturnOptions;
}

AftMessDeck* AftMessDeck::Instance()
{
	static AftMessDeck instance;
	return &instance;
}

void AftMessDeck::Enter(IPerson* pEntity)
{  
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Entering the Aft Mess Deck of the USS Enterprise";
	#endif

	// Add entity to the location
	AddEntityToLocation(pEntity);
}

void AftMessDeck::Execute(IPerson* pEntity)
{
//	if (true)
//		pEntity->GetLocationMachine()->ChangeLocation(BoatOutsideShip::Instance());
}

void AftMessDeck::Exit(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Exiting the Aft Mess Deck of the USS Enterprise";
	#endif

	// Remove entity from location
	RemoveEntityFromLocation(pEntity);
}

bool AftMessDeck::OnMessage(IPerson* agent, const Telegram& msg)
{
	//send msg to global message handler
	return false;
}

CItems* AftMessDeck::RetrieveItemsAtLocation()
{
	SItem* sTempItem = nullptr;
	CItems* pVisibleList = new CItems();
	// Iterate through items list to add to visible list
	for (int i = 0; i < m_oItems.NumberOfItems(); i++)
	{
		sTempItem = m_oItems.RetrieveItem(i);
		// Check if item is visible, and add to return list if it is
		if (sTempItem->ItemVisibleToPlayer)
			pVisibleList->AddItem(sTempItem);
	}
	return pVisibleList;
}

SItem* AftMessDeck::RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy)
{
	userCommand = CUserInterface::UserSelectionPrompt(m_sUserOptions, AftMessDeck::Instance(), pEnemy);
	
	if (userCommand == "FORE")
	{
		pEntity->GetLocationMachine()->ChangeLocation(AftBombXferArea::Instance());

		return nullptr;
	}
	else if (userCommand == "AFT")
	{
		pEntity->GetLocationMachine()->ChangeLocation(SecondDeckPart1::Instance());

		return nullptr;
	}
	else
	{
		return nullptr;
	}
}

//------------------------------------------------------------------------methods for AftBombXferArea
AftBombXferArea::AftBombXferArea() : m_oItems()
{
	m_sUserOptions.location_name = "the Aft Bomb Transfer Area of the USS Enterprise";

	m_sUserOptions.locations_available[0] = "PORT";
	m_sUserOptions.locations_available[1] = "STBD";
	m_sUserOptions.locations_available[2] = "FORE";
	m_sUserOptions.locations_available[3] = "AFT";
	m_sUserOptions.locations_available[4] = "";
	m_sUserOptions.locations_available[5] = "";

	m_sUserOptions.other_options_available[0] = "OPEN ELEVATOR";
	m_sUserOptions.other_options_available[1] = "";
	m_sUserOptions.other_options_available[2] = "";
	m_sUserOptions.other_options_available[3] = "";
	m_sUserOptions.other_options_available[4] = "";
	m_sUserOptions.other_options_available[5] = "";
	m_sUserOptions.other_options_available[6] = "";
	m_sUserOptions.other_options_available[7] = "";
	m_sUserOptions.other_options_available[8] = "";
	m_sUserOptions.other_options_available[9] = "";

	// Add security personnel to area
	CGenericPerson* pSecurityGuard = new CGenericPerson(ent_Security1, this);
	SItem* pMachineGune = new SItem();
	pMachineGune->Name = "M-16";
	pMachineGune->DamageDonePerAttack = 10;
	pMachineGune->ProjectileWeapon = true;
	pMachineGune->AmmoInWeapon = 90;
	pSecurityGuard->AddItemToInventory(pMachineGune);
	AddEntityToLocation(pSecurityGuard);
}

CLocation** AftBombXferArea::RequestDirectionsPossible(int& NumberOfDirections)
{
	NumberOfDirections = 2;
	CLocation** aReturnOptions = new CLocation*[NumberOfDirections];
	aReturnOptions[0] = PropulsionBlock::Instance();
	aReturnOptions[1] = AftMessDeck::Instance();
	return aReturnOptions;
}

AftBombXferArea* AftBombXferArea::Instance()
{
	static AftBombXferArea instance;
	return &instance;
}

void AftBombXferArea::Enter(IPerson* pEntity)
{  
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Entering the Aft Bomb Transfer Area of the USS Enterprise";
	#endif

	// Add entity to the location
	AddEntityToLocation(pEntity);
}

void AftBombXferArea::Execute(IPerson* pEntity)
{
	// No Logic Needed Here Yet
}

void AftBombXferArea::Exit(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Exiting the Aft Bomb Transfer Area of the USS Enterprise";
	#endif

	// Remove entity from location
	RemoveEntityFromLocation(pEntity);
}

bool AftBombXferArea::OnMessage(IPerson* agent, const Telegram& msg)
{
	//send msg to global message handler
	return false;
}

CItems* AftBombXferArea::RetrieveItemsAtLocation()
{
	SItem* sTempItem = nullptr;
	CItems* pVisibleList = new CItems();
	// Iterate through items list to add to visible list
	for (int i = 0; i < m_oItems.NumberOfItems(); i++)
	{
		sTempItem = m_oItems.RetrieveItem(i);
		// Check if item is visible, and add to return list if it is
		if (sTempItem->ItemVisibleToPlayer)
			pVisibleList->AddItem(sTempItem);
	}
	return pVisibleList;
}

SItem* AftBombXferArea::RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy)
{
	userCommand = CUserInterface::UserSelectionPrompt(m_sUserOptions, AftBombXferArea::Instance(), pEnemy);
	
	if (userCommand == "FORE")
	{
		pEntity->GetLocationMachine()->ChangeLocation(PropulsionBlock::Instance());

		return nullptr;
	}
	else if (userCommand == "AFT")
	{
		pEntity->GetLocationMachine()->ChangeLocation(AftMessDeck::Instance());

		return nullptr;
	}
	else if (userCommand == "PORT")
	{
//		pEntity->GetLocationMachine()->ChangeLocation(SecondDeckPart1::Instance());

		return nullptr;
	}
	else if (userCommand == "STBD")
	{
//		pEntity->GetLocationMachine()->ChangeLocation(SecondDeckPart1::Instance());

		return nullptr;
	}
	else if (userCommand == "UP")
	{
//		pEntity->GetLocationMachine()->ChangeLocation(SecondDeckPart1::Instance());

		return nullptr;
	}
	else if (userCommand == "DOWN")
	{
//		pEntity->GetLocationMachine()->ChangeLocation(SecondDeckPart1::Instance());

		return nullptr;
	}
	else if (userCommand == "ATTACK") 
	{
		return nullptr;
	}
	else if (userCommand == "SEARCH")
	{
		return nullptr;
	}
	else
	{
		return nullptr;
	}
}

//------------------------------------------------------------------------methods for PropulsionBlock
PropulsionBlock::PropulsionBlock() : m_oItems()
{
	m_sUserOptions.location_name = "Propulsion Block of the USS Enterprise";

	m_sUserOptions.locations_available[0] = "FORE";
	m_sUserOptions.locations_available[1] = "AFT";
	m_sUserOptions.locations_available[2] = "";
	m_sUserOptions.locations_available[3] = "";
	m_sUserOptions.locations_available[4] = "";
	m_sUserOptions.locations_available[5] = "";

	m_sUserOptions.other_options_available[0] = "";
	m_sUserOptions.other_options_available[1] = "";
	m_sUserOptions.other_options_available[2] = "";
	m_sUserOptions.other_options_available[3] = "";
	m_sUserOptions.other_options_available[4] = "";
	m_sUserOptions.other_options_available[5] = "";
	m_sUserOptions.other_options_available[6] = "";
	m_sUserOptions.other_options_available[7] = "";
	m_sUserOptions.other_options_available[8] = "";
	m_sUserOptions.other_options_available[9] = "";
}

CLocation** PropulsionBlock::RequestDirectionsPossible(int& NumberOfDirections)
{
	NumberOfDirections = 2;
	CLocation** aReturnOptions = new CLocation*[NumberOfDirections];
	aReturnOptions[0] = AftBombXferArea::Instance();
	aReturnOptions[1] = SecondDeckPart2::Instance();
	return aReturnOptions;
}

PropulsionBlock* PropulsionBlock::Instance()
{
	static PropulsionBlock instance;
	return &instance;
}

void PropulsionBlock::Enter(IPerson* pEntity)
{  
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Entering the Propulsion Block";
	#endif

	// Add entity to the location
	AddEntityToLocation(pEntity);
}

void PropulsionBlock::Execute(IPerson* pEntity)
{
	// There is no location logic needed here.
}

void PropulsionBlock::Exit(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Exiting the Propulsion Block";
	#endif

	// Remove entity from location
	RemoveEntityFromLocation(pEntity);
}

bool PropulsionBlock::OnMessage(IPerson* agent, const Telegram& msg)
{
	//send msg to global message handler
	return false;
}

CItems* PropulsionBlock::RetrieveItemsAtLocation()
{
	SItem* sTempItem = nullptr;
	CItems* pVisibleList = new CItems();
	// Iterate through items list to add to visible list
	for (int i = 0; i < m_oItems.NumberOfItems(); i++)
	{
		sTempItem = m_oItems.RetrieveItem(i);
		// Check if item is visible, and add to return list if it is
		if (sTempItem->ItemVisibleToPlayer)
			pVisibleList->AddItem(sTempItem);
	}
	return pVisibleList;
}

SItem* PropulsionBlock::RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy)
{
	userCommand = CUserInterface::UserSelectionPrompt(m_sUserOptions, PropulsionBlock::Instance(), pEnemy);
	
	if (userCommand == "FORE")
	{
		pEntity->GetLocationMachine()->ChangeLocation(SecondDeckPart2::Instance());

		return nullptr;
	}
	else if (userCommand == "AFT")
	{
		pEntity->GetLocationMachine()->ChangeLocation(AftBombXferArea::Instance());

		return nullptr;
	}
	else
	{
		return nullptr;
	}
}

//------------------------------------------------------------------------methods for SecondDeckPart2
SecondDeckPart2::SecondDeckPart2() : m_oItems()
{
	m_sUserOptions.location_name = "2nd Deck of the USS Enterprise";

	m_sUserOptions.locations_available[0] = "PORT";
	m_sUserOptions.locations_available[1] = "STBD";
	m_sUserOptions.locations_available[2] = "FORE";
	m_sUserOptions.locations_available[3] = "AFT";
	m_sUserOptions.locations_available[4] = "";
	m_sUserOptions.locations_available[5] = "";

	m_sUserOptions.other_options_available[0] = "LOOK AROUND";
	m_sUserOptions.other_options_available[1] = "";
	m_sUserOptions.other_options_available[2] = "";
	m_sUserOptions.other_options_available[3] = "";
	m_sUserOptions.other_options_available[4] = "";
	m_sUserOptions.other_options_available[5] = "";
	m_sUserOptions.other_options_available[6] = "";
	m_sUserOptions.other_options_available[7] = "";
	m_sUserOptions.other_options_available[8] = "";
	m_sUserOptions.other_options_available[9] = "";
}

CLocation** SecondDeckPart2::RequestDirectionsPossible(int& NumberOfDirections)
{
	NumberOfDirections = 4;
	CLocation** aReturnOptions = new CLocation*[NumberOfDirections];
	aReturnOptions[0] = FwdMessDeck::Instance();
	aReturnOptions[1] = PropulsionBlock::Instance();
	aReturnOptions[2] = MedicalOffice::Instance();
	aReturnOptions[3] = EDivisionOffice::Instance();
	return aReturnOptions;
}

SecondDeckPart2* SecondDeckPart2::Instance()
{
	static SecondDeckPart2 instance;
	return &instance;
}

void SecondDeckPart2::Enter(IPerson* pEntity)
{  
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Entering the 2nd Deck Part 2";
	#endif

	// Add entity to the location
	AddEntityToLocation(pEntity);
}

void SecondDeckPart2::Execute(IPerson* pEntity)
{
	// There is no location logic needed here.
}

void SecondDeckPart2::Exit(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Exiting  the 2nd Deck Part 2";
	#endif

	// Remove entity from location
	RemoveEntityFromLocation(pEntity);
}

bool SecondDeckPart2::OnMessage(IPerson* agent, const Telegram& msg)
{
	//send msg to global message handler
	return false;
}

CItems* SecondDeckPart2::RetrieveItemsAtLocation()
{
	SItem* sTempItem = nullptr;
	CItems* pVisibleList = new CItems();
	// Iterate through items list to add to visible list
	for (int i = 0; i < m_oItems.NumberOfItems(); i++)
	{
		sTempItem = m_oItems.RetrieveItem(i);
		// Check if item is visible, and add to return list if it is
		if (sTempItem->ItemVisibleToPlayer)
			pVisibleList->AddItem(sTempItem);
	}
	return pVisibleList;
}

SItem* SecondDeckPart2::RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy)
{
	userCommand = CUserInterface::UserSelectionPrompt(m_sUserOptions, SecondDeckPart2::Instance(), pEnemy);
	
	if (userCommand == "FORE")
	{
		pEntity->GetLocationMachine()->ChangeLocation(FwdMessDeck::Instance());

		return nullptr;
	}
	else if (userCommand == "AFT")
	{
		pEntity->GetLocationMachine()->ChangeLocation(PropulsionBlock::Instance());

		return nullptr;
	}
	else if (userCommand == "PORT")
	{
		pEntity->GetLocationMachine()->ChangeLocation(EDivisionOffice::Instance());

		return nullptr;
	}
	else if (userCommand == "STBD")
	{
		pEntity->GetLocationMachine()->ChangeLocation(MedicalOffice::Instance());

		return nullptr;
	}
	else
	{
		return nullptr;
	}
}

//------------------------------------------------------------------------methods for EDivisionOffice
EDivisionOffice::EDivisionOffice() : m_oItems()
{
	m_sUserOptions.location_name = "E-Division Office";

	m_sUserOptions.locations_available[0] = "";
	m_sUserOptions.locations_available[1] = "STBD";
	m_sUserOptions.locations_available[2] = "";
	m_sUserOptions.locations_available[3] = "";
	m_sUserOptions.locations_available[4] = "";
	m_sUserOptions.locations_available[5] = "";

	m_sUserOptions.other_options_available[0] = "LOOK AROUND";
	m_sUserOptions.other_options_available[1] = "";
	m_sUserOptions.other_options_available[2] = "";
	m_sUserOptions.other_options_available[3] = "";
	m_sUserOptions.other_options_available[4] = "";
	m_sUserOptions.other_options_available[5] = "";
	m_sUserOptions.other_options_available[6] = "";
	m_sUserOptions.other_options_available[7] = "";
	m_sUserOptions.other_options_available[8] = "";
	m_sUserOptions.other_options_available[9] = "";
}

CLocation** EDivisionOffice::RequestDirectionsPossible(int& NumberOfDirections)
{
	NumberOfDirections = 1;
	CLocation** aReturnOptions = new CLocation*[NumberOfDirections];
	aReturnOptions[0] = SecondDeckPart2::Instance();
	return aReturnOptions;
}

EDivisionOffice* EDivisionOffice::Instance()
{
	static EDivisionOffice instance;
	return &instance;
}

void EDivisionOffice::Enter(IPerson* pEntity)
{  
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Entering the E-Division Office";
	#endif

	// Add entity to the location
	AddEntityToLocation(pEntity);
}

void EDivisionOffice::Execute(IPerson* pEntity)
{
	// There is no location logic needed here.
}

void EDivisionOffice::Exit(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Exiting  the E-Division Office";
	#endif

	// Remove entity from location
	RemoveEntityFromLocation(pEntity);
}

bool EDivisionOffice::OnMessage(IPerson* agent, const Telegram& msg)
{
	//send msg to global message handler
	return false;
}

CItems* EDivisionOffice::RetrieveItemsAtLocation()
{
	SItem* sTempItem = nullptr;
	CItems* pVisibleList = new CItems();
	// Iterate through items list to add to visible list
	for (int i = 0; i < m_oItems.NumberOfItems(); i++)
	{
		sTempItem = m_oItems.RetrieveItem(i);
		// Check if item is visible, and add to return list if it is
		if (sTempItem->ItemVisibleToPlayer)
			pVisibleList->AddItem(sTempItem);
	}
	return pVisibleList;
}

SItem* EDivisionOffice::RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy)
{
	userCommand = CUserInterface::UserSelectionPrompt(m_sUserOptions, EDivisionOffice::Instance(), pEnemy);
	
	if (userCommand == "STBD")
	{
		pEntity->GetLocationMachine()->ChangeLocation(SecondDeckPart2::Instance());

		return nullptr;
	}
	else
	{
		return nullptr;
	}
}

//------------------------------------------------------------------------methods for MedicalOffice
MedicalOffice::MedicalOffice() : m_oItems()
{
	m_sUserOptions.location_name = "Medical";

	m_sUserOptions.locations_available[0] = "PORT";
	m_sUserOptions.locations_available[1] = "";
	m_sUserOptions.locations_available[2] = "";
	m_sUserOptions.locations_available[3] = "";
	m_sUserOptions.locations_available[4] = "";
	m_sUserOptions.locations_available[5] = "";

	m_sUserOptions.other_options_available[0] = "LOOK AROUND";
	m_sUserOptions.other_options_available[1] = "";
	m_sUserOptions.other_options_available[2] = "";
	m_sUserOptions.other_options_available[3] = "";
	m_sUserOptions.other_options_available[4] = "";
	m_sUserOptions.other_options_available[5] = "";
	m_sUserOptions.other_options_available[6] = "";
	m_sUserOptions.other_options_available[7] = "";
	m_sUserOptions.other_options_available[8] = "";
	m_sUserOptions.other_options_available[9] = "";
}

CLocation** MedicalOffice::RequestDirectionsPossible(int& NumberOfDirections)
{
	NumberOfDirections = 1;
	CLocation** aReturnOptions = new CLocation*[NumberOfDirections];
	aReturnOptions[0] = SecondDeckPart2::Instance();
	return aReturnOptions;
}

MedicalOffice* MedicalOffice::Instance()
{
	static MedicalOffice instance;
	return &instance;
}

void MedicalOffice::Enter(IPerson* pEntity)
{  
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Entering Medical";
	#endif

	// Add entity to the location
	AddEntityToLocation(pEntity);
}

void MedicalOffice::Execute(IPerson* pEntity)
{
	// There is no location logic needed here.
}

void MedicalOffice::Exit(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Exiting Medical";
	#endif

	// Remove entity from location
	RemoveEntityFromLocation(pEntity);
}

bool MedicalOffice::OnMessage(IPerson* agent, const Telegram& msg)
{
	//send msg to global message handler
	return false;
}

CItems* MedicalOffice::RetrieveItemsAtLocation()
{
	SItem* sTempItem = nullptr;
	CItems* pVisibleList = new CItems();
	// Iterate through items list to add to visible list
	for (int i = 0; i < m_oItems.NumberOfItems(); i++)
	{
		sTempItem = m_oItems.RetrieveItem(i);
		// Check if item is visible, and add to return list if it is
		if (sTempItem->ItemVisibleToPlayer)
			pVisibleList->AddItem(sTempItem);
	}
	return pVisibleList;
}

SItem* MedicalOffice::RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy)
{
	userCommand = CUserInterface::UserSelectionPrompt(m_sUserOptions, MedicalOffice::Instance(), pEnemy);
	
	if (userCommand == "PORT")
	{
		pEntity->GetLocationMachine()->ChangeLocation(SecondDeckPart2::Instance());

		return nullptr;
	}
	else
	{
		return nullptr;
	}
}

//------------------------------------------------------------------------methods for FwdMessDeck
FwdMessDeck::FwdMessDeck() : m_oItems()
{
	m_sUserOptions.location_name = "the Forward Mess Deck";

	m_sUserOptions.locations_available[0] = "FORE";
	m_sUserOptions.locations_available[1] = "AFT";
	m_sUserOptions.locations_available[2] = "";
	m_sUserOptions.locations_available[3] = "";
	m_sUserOptions.locations_available[4] = "";
	m_sUserOptions.locations_available[5] = "";

	m_sUserOptions.other_options_available[0] = "";
	m_sUserOptions.other_options_available[1] = "";
	m_sUserOptions.other_options_available[2] = "";
	m_sUserOptions.other_options_available[3] = "";
	m_sUserOptions.other_options_available[4] = "";
	m_sUserOptions.other_options_available[5] = "";
	m_sUserOptions.other_options_available[6] = "";
	m_sUserOptions.other_options_available[7] = "";
	m_sUserOptions.other_options_available[8] = "";
	m_sUserOptions.other_options_available[9] = "";
}

CLocation** FwdMessDeck::RequestDirectionsPossible(int& NumberOfDirections)
{
	NumberOfDirections = 2;
	CLocation** aReturnOptions = new CLocation*[NumberOfDirections];
	aReturnOptions[0] = SecondDeckPart2::Instance();
	aReturnOptions[1] = FwdBombXferArea::Instance();
	return aReturnOptions;
}

FwdMessDeck* FwdMessDeck::Instance()
{
	static FwdMessDeck instance;
	return &instance;
}

void FwdMessDeck::Enter(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Entering the forward mess deck";
	#endif

	// Add entity to the location
	AddEntityToLocation(pEntity);
}

void FwdMessDeck::Execute(IPerson* pEntity)
{
//	if (true)
//		pEntity->GetLocationMachine()->ChangeLocation(EDivBerthing::Instance());
}

void FwdMessDeck::Exit(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Exiting the forward mess deck";
	#endif

	// Remove entity from location
	RemoveEntityFromLocation(pEntity);
}

bool FwdMessDeck::OnMessage(IPerson* agent, const Telegram& msg)
{
	//send msg to global message handler
	return false;
}

CItems* FwdMessDeck::RetrieveItemsAtLocation()
{
	SItem* sTempItem = nullptr;
	CItems* pVisibleList = new CItems();
	// Iterate through items list to add to visible list
	for (int i = 0; i < m_oItems.NumberOfItems(); i++)
	{
		sTempItem = m_oItems.RetrieveItem(i);
		// Check if item is visible, and add to return list if it is
		if (sTempItem->ItemVisibleToPlayer)
			pVisibleList->AddItem(sTempItem);
	}
	return pVisibleList;
}

SItem* FwdMessDeck::RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy)
{
	userCommand = CUserInterface::UserSelectionPrompt(m_sUserOptions, FwdMessDeck::Instance(), pEnemy);
	
	if (userCommand == "FORE")
	{
		pEntity->GetLocationMachine()->ChangeLocation(FwdBombXferArea::Instance());

		return nullptr;
	}
	else if (userCommand == "AFT")
	{
		pEntity->GetLocationMachine()->ChangeLocation(SecondDeckPart2::Instance());

		return nullptr;
	}
	else
	{
		return nullptr;
	}
}

//------------------------------------------------------------------------methods for FwdBombXferArea
FwdBombXferArea::FwdBombXferArea() : m_oItems()
{
	m_sUserOptions.location_name = "the Forward Bomb Transfer Area";

	m_sUserOptions.locations_available[0] = "AFT";
	m_sUserOptions.locations_available[1] = "UP";
	m_sUserOptions.locations_available[2] = "";
	m_sUserOptions.locations_available[3] = "";
	m_sUserOptions.locations_available[4] = "";
	m_sUserOptions.locations_available[5] = "";

	m_sUserOptions.other_options_available[0] = "";
	m_sUserOptions.other_options_available[1] = "";
	m_sUserOptions.other_options_available[2] = "";
	m_sUserOptions.other_options_available[3] = "";
	m_sUserOptions.other_options_available[4] = "";
	m_sUserOptions.other_options_available[5] = "";
	m_sUserOptions.other_options_available[6] = "";
	m_sUserOptions.other_options_available[7] = "";
	m_sUserOptions.other_options_available[8] = "";
	m_sUserOptions.other_options_available[9] = "";
}

CLocation** FwdBombXferArea::RequestDirectionsPossible(int& NumberOfDirections)
{
	NumberOfDirections = 2;
	CLocation** aReturnOptions = new CLocation*[NumberOfDirections];
	aReturnOptions[0] = FwdMessDeck::Instance();
	aReturnOptions[1] = HangarBayPart1::Instance();
	return aReturnOptions;
}

FwdBombXferArea* FwdBombXferArea::Instance()
{
	static FwdBombXferArea instance;
	return &instance;
}

void FwdBombXferArea::Enter(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Entering the forward bomb transfer area";
	#endif

	// Add entity to the location
	AddEntityToLocation(pEntity);
}

void FwdBombXferArea::Execute(IPerson* pEntity)
{
//	if (true)
//		pEntity->GetLocationMachine()->ChangeLocation(EDivBerthing::Instance());
}

void FwdBombXferArea::Exit(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Exiting the forward bomb transfer area";
	#endif

	// Remove entity from location
	RemoveEntityFromLocation(pEntity);
}

bool FwdBombXferArea::OnMessage(IPerson* agent, const Telegram& msg)
{
	//send msg to global message handler
	return false;
}

CItems* FwdBombXferArea::RetrieveItemsAtLocation()
{
	SItem* sTempItem = nullptr;
	CItems* pVisibleList = new CItems();
	// Iterate through items list to add to visible list
	for (int i = 0; i < m_oItems.NumberOfItems(); i++)
	{
		sTempItem = m_oItems.RetrieveItem(i);
		// Check if item is visible, and add to return list if it is
		if (sTempItem->ItemVisibleToPlayer)
			pVisibleList->AddItem(sTempItem);
	}
	return pVisibleList;
}

SItem* FwdBombXferArea::RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy)
{
	userCommand = CUserInterface::UserSelectionPrompt(m_sUserOptions, FwdBombXferArea::Instance(), pEnemy);
	
	if (userCommand == "FORE")
	{
//		pEntity->GetLocationMachine()->ChangeLocation(SecondDeckPart2::Instance());

		return nullptr;
	}
	else if (userCommand == "AFT")
	{
		pEntity->GetLocationMachine()->ChangeLocation(FwdMessDeck::Instance());

		return nullptr;
	}
	else if (userCommand == "UP")
	{
		pEntity->GetLocationMachine()->ChangeLocation(HangarBayPart1::Instance());

		return nullptr;
	}
	else
	{
		return nullptr;
	}
}

//------------------------------------------------------------------------methods for HangarBayPart1
HangarBayPart1::HangarBayPart1() : m_oItems()
{
	m_sUserOptions.location_name = "the forward-most portion of the Hangar Bay";

	m_sUserOptions.locations_available[0] = "STBD";
	m_sUserOptions.locations_available[1] = "AFT";
	m_sUserOptions.locations_available[2] = "DOWN";
	m_sUserOptions.locations_available[3] = "";
	m_sUserOptions.locations_available[4] = "";
	m_sUserOptions.locations_available[5] = "";

	m_sUserOptions.other_options_available[0] = "";
	m_sUserOptions.other_options_available[1] = "";
	m_sUserOptions.other_options_available[2] = "";
	m_sUserOptions.other_options_available[3] = "";
	m_sUserOptions.other_options_available[4] = "";
	m_sUserOptions.other_options_available[5] = "";
	m_sUserOptions.other_options_available[6] = "";
	m_sUserOptions.other_options_available[7] = "";
	m_sUserOptions.other_options_available[8] = "";
	m_sUserOptions.other_options_available[9] = "";
}

CLocation** HangarBayPart1::RequestDirectionsPossible(int& NumberOfDirections)
{
	NumberOfDirections = 2;
	CLocation** aReturnOptions = new CLocation*[NumberOfDirections];
	aReturnOptions[0] = Elevator1::Instance();
	aReturnOptions[1] = FwdBombXferArea::Instance();
	return aReturnOptions;
}

HangarBayPart1* HangarBayPart1::Instance()
{
	static HangarBayPart1 instance;
	return &instance;
}

void HangarBayPart1::Enter(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Entering the Hangar Bay Part 1";
	#endif

	// Add entity to the location
	AddEntityToLocation(pEntity);
}

void HangarBayPart1::Execute(IPerson* pEntity)
{
//	if (true)
//		pEntity->GetLocationMachine()->ChangeLocation(EDivBerthing::Instance());
}

void HangarBayPart1::Exit(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Exiting the Hangar Bay Part 1";
	#endif

	// Remove entity from location
	RemoveEntityFromLocation(pEntity);
}

bool HangarBayPart1::OnMessage(IPerson* agent, const Telegram& msg)
{
	//send msg to global message handler
	return false;
}

CItems* HangarBayPart1::RetrieveItemsAtLocation()
{
	SItem* sTempItem = nullptr;
	CItems* pVisibleList = new CItems();
	// Iterate through items list to add to visible list
	for (int i = 0; i < m_oItems.NumberOfItems(); i++)
	{
		sTempItem = m_oItems.RetrieveItem(i);
		// Check if item is visible, and add to return list if it is
		if (sTempItem->ItemVisibleToPlayer)
			pVisibleList->AddItem(sTempItem);
	}
	return pVisibleList;
}

SItem* HangarBayPart1::RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy)
{
	userCommand = CUserInterface::UserSelectionPrompt(m_sUserOptions, HangarBayPart1::Instance(), pEnemy);
	
	if (userCommand == "STBD")
	{
		pEntity->GetLocationMachine()->ChangeLocation(Elevator1::Instance());

		return nullptr;
	}
	else if (userCommand == "AFT")
	{
//		pEntity->GetLocationMachine()->ChangeLocation(FwdMessDeck::Instance());

		return nullptr;
	}
	else if (userCommand == "DOWN")
	{
		pEntity->GetLocationMachine()->ChangeLocation(FwdBombXferArea::Instance());

		return nullptr;
	}
	else
	{
		return nullptr;
	}
}

//------------------------------------------------------------------------methods for Elevator1
Elevator1::Elevator1() : m_oItems()
{
	m_sUserOptions.location_name = "the Aircraft Elevator #1";

	m_sUserOptions.locations_available[0] = "PORT";
	m_sUserOptions.locations_available[1] = "DOWN";
	m_sUserOptions.locations_available[2] = "";
	m_sUserOptions.locations_available[3] = "";
	m_sUserOptions.locations_available[4] = "";
	m_sUserOptions.locations_available[5] = "";

	m_sUserOptions.other_options_available[0] = "";
	m_sUserOptions.other_options_available[1] = "";
	m_sUserOptions.other_options_available[2] = "";
	m_sUserOptions.other_options_available[3] = "";
	m_sUserOptions.other_options_available[4] = "";
	m_sUserOptions.other_options_available[5] = "";
	m_sUserOptions.other_options_available[6] = "";
	m_sUserOptions.other_options_available[7] = "";
	m_sUserOptions.other_options_available[8] = "";
	m_sUserOptions.other_options_available[9] = "";
}

CLocation** Elevator1::RequestDirectionsPossible(int& NumberOfDirections)
{
	NumberOfDirections = 2;
	CLocation** aReturnOptions = new CLocation*[NumberOfDirections];
	aReturnOptions[0] = HangarBayPart1::Instance();
	aReturnOptions[1] = BoatOutsideShip::Instance();
	return aReturnOptions;
}

Elevator1* Elevator1::Instance()
{
	static Elevator1 instance;
	return &instance;
}

void Elevator1::Enter(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Entering Elevator #1";
	#endif

	// Add entity to the location
	AddEntityToLocation(pEntity);
}

void Elevator1::Execute(IPerson* pEntity)
{
//	if (true)
//		pEntity->GetLocationMachine()->ChangeLocation(EDivBerthing::Instance());
}

void Elevator1::Exit(IPerson* pEntity)
{
	#ifdef DEBUG_SECTION
		// Output status of the entity
		SetTextColor(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
		cout << endl << pEntity->Name() << ": " << "Exiting Elevator #1";
	#endif

	// Remove entity from location
	RemoveEntityFromLocation(pEntity);
}

bool Elevator1::OnMessage(IPerson* agent, const Telegram& msg)
{
	//send msg to global message handler
	return false;
}

CItems* Elevator1::RetrieveItemsAtLocation()
{
	SItem* sTempItem = nullptr;
	CItems* pVisibleList = new CItems();
	// Iterate through items list to add to visible list
	for (int i = 0; i < m_oItems.NumberOfItems(); i++)
	{
		sTempItem = m_oItems.RetrieveItem(i);
		// Check if item is visible, and add to return list if it is
		if (sTempItem->ItemVisibleToPlayer)
			pVisibleList->AddItem(sTempItem);
	}
	return pVisibleList;
}

SItem* Elevator1::RequestUserInput(IPerson* pEntity, string& userCommand, IPerson*& pEnemy)
{
	userCommand = CUserInterface::UserSelectionPrompt(m_sUserOptions, Elevator1::Instance(), pEnemy);
	
	if (userCommand == "PORT")
	{
		pEntity->GetLocationMachine()->ChangeLocation(HangarBayPart1::Instance());

		return nullptr;
	}
	else if (userCommand == "DOWN")
	{
		pEntity->GetLocationMachine()->ChangeLocation(BoatOutsideShip::Instance());

		return nullptr;
	}
	else
	{
		return nullptr;
	}
}

